function Dog(name) {
    this.name = name;
}
Dog.prototype.bark = function () {
    console.log('wangwang');
}
Dog.prototype.sayName = function () {
    console.log('my name is ' + this.name);
}
// let sanmao = new Dog('三毛');  //我们的需求是重写内置的NEW操作，实现和其一样的效果


/* 
 * _new 模拟内置的new操作，创造某个类的实例
 * @params 
 *   Ctor：操作的构造函数（类）
 *   params：数组，存储给构造函数传递的实参
 * @return 
 *   我们创建的实例对象
 */
/* 
// 基础版本
const _new = function _new(Ctor, ...params) {
    // @1 创建 Ctor(Dog) 的实例对象「其__proto__指向Ctor.prototype」
    let obj = {};
    obj.__proto__ = Ctor.prototype;

    // @2 把构造函数执行：传递实参值 && 函数中的this需要指向创建的实例对象
    let result = Ctor.call(obj, ...params);

    // @3 监测其返回值，来决定最后返回实例还是其内部的返回值
    if (isObject(result)) return result;
    return obj;
}; 
*/

const isObject = function isObject(obj) {
    return obj !== null && /^(object|function)$/.test(typeof obj);
};
const _new = function _new(Ctor, ...params) {
    if (typeof Ctor !== "function" || !Ctor.prototype || Ctor === Symbol || Ctor === BigInt) {
        throw new TypeError("Ctor is not a constructor");
    }
    let result, obj;
    obj = Object.create(Ctor.prototype);
    result = Ctor.apply(obj, params);
    if (isObject(result)) return result;
    return obj;
};
let sanmao = _new(Dog, '三毛');
sanmao.bark(); //=>"wangwang"
sanmao.sayName(); //=>"my name is 三毛"
console.log(sanmao instanceof Dog); //=>true